﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Soft.Net
{

    /// <summary>
    /// 接收UDP广播
    /// </summary>
    public abstract class UDPBroadcastReceive : BaseUDPBroadcast
    {

        /// <summary>
        /// 开始接收广播
        /// </summary>
        /// <returns></returns>
        public override Result Start()
        {
            Result result = new Result();
            if (base.State == ServerState.Stopped || base.State == ServerState.Error)
            {
                base.State = ServerState.Starting;
                try
                {
                    this.mBuffer = new byte[(int)base.MaxBufferSize];
                    base.IPEndPoint = new IPEndPoint(IPAddress.Any, base.Port);
                    base.UDPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                    base.UDPSocket.Bind(base.IPEndPoint);
                    base.State = ServerState.Started;
                    base.Start();
                    this.mSocketAsyncEventArgs = new SocketAsyncEventArgs();
                    this.mSocketAsyncEventArgs.Completed += this.SocketAsyncEventArgs_Completed;
                    this.mSocketAsyncEventArgs.RemoteEndPoint = base.IPEndPoint;
                    this.mSocketAsyncEventArgs.SetBuffer(this.mBuffer, 0, (int)base.MaxBufferSize);
                    //从指定的网路驱动中异步接收数据
                    base.UDPSocket.ReceiveFromAsync(this.mSocketAsyncEventArgs);
                }
                catch (Exception exception)
                {
                    base.State = ServerState.Error;
                    result.AddError(exception, null);
                }
            }
            return result;
        }

 
        /// <summary>
        /// Socket事件完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e)
        {
            if (e.SocketError == SocketError.Success)
            {
                if (e.BytesTransferred <= 0)
                {
                    goto IL_7C;
                }
                try
                {
                    byte[] array = new byte[e.BytesTransferred];
                    Array.Copy(e.Buffer, e.Offset, array, 0, e.BytesTransferred);
                    //开启后台线程 处理数据逻辑
                    Thread thread = new Thread(new ParameterizedThreadStart(this.CallOnReceived))
                    {
                        IsBackground = true
                    };
                    thread.Start(array);
                    goto IL_7C;
                }
                catch (Exception e2)
                {
                    this.OnError(e2);
                    goto IL_7C;
                }
            }
            this.OnError(e.SocketError.ToString());
        IL_7C:
            if (e.SocketError != SocketError.OperationAborted)
            {
                base.UDPSocket.ReceiveFromAsync(this.mSocketAsyncEventArgs);
            }
        }


        /// <summary>
        /// 接收消息调用的方法
        /// </summary>
        /// <param name="state"></param>
        private void CallOnReceived(object state)
        {
            try
            {
                this.OnReceived(state);
            }
            catch
            {
            }
        }

        /// <summary>
        /// 接收消息执行的逻辑
        /// </summary>
        /// <param name="state"></param>
        protected abstract void OnReceived(object state);
    }
}
